package com.buer.train.api;

import com.buer.train.business.domain.*;
import com.buer.train.business.dto.RoleDTO;
import com.buer.train.business.dto.UserDTO;
import com.buer.train.business.service.*;
import com.buer.train.common.annotation.Auth;
import com.buer.train.common.eumn.ResultEnum;
import com.buer.train.common.holder.LoginUser;
import com.buer.train.common.holder.LoginUserHolder;
import com.buer.train.common.utils.BaseResult;
import com.buer.train.common.utils.MD5Utils;
import com.buer.train.common.utils.Tree;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
@Api(tags = {"用户模块接口"})
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private DeptService deptService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private MenuService menuService;



    @RequestMapping(value = "/user/info", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("获取当前用户信息")
    @Auth
    public BaseResult userInfo() {
        LoginUser loginUserHolder = LoginUserHolder.getLoginUserHolder();
        UserDO userDO = userService.get(loginUserHolder.getUserId());
        DeptDO deptDO = deptService.get(userDO.getDeptId());
        userDO.setDeptName(deptDO.getName());
        userDO.setPassword(null);
        return BaseResult.build(ResultEnum.SUCCESS, userDO);
    }


    @RequestMapping(value = "/user/list", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("用户列表-所有用户")
    @Auth(value = "user:user:list")
    public BaseResult userList(@RequestBody Map<String, Object> params) {
        PageInfo<UserDO> userList = userService.getUserList(params);
        Map map = new HashMap<>();
        map.put("list", userList.getList());
        map.put("total", userList.getTotal());
        return BaseResult.build(ResultEnum.SUCCESS, map);
    }

    @RequestMapping(value = "/user/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("用户添加")
    @Auth(value = "user:user:add")
    @Transactional
    public BaseResult userAdd(@RequestBody UserDTO userDTO) {
        //保存用户
        UserDO userDO=new UserDO();
        userDO.setUsername(userDTO.getUsername());
        userDO.setName(userDTO.getName());
        userDO.setEmail(userDTO.getEmail());
        userDO.setMobile(userDTO.getMobile());
        String reqPassWord = MD5Utils.encrypt(userDTO.getUsername(), userDTO.getPassword());
        userDO.setPassword(reqPassWord);
        userDO.setStatus(1);
        userDO.setDeptId(userDTO.getDeptId());
        userDO.setGmtCreate(new Date());
        userService.save(userDO);

        //保存用户和角色的关系
        UserRoleDO userRoleDO=new UserRoleDO();
        userRoleDO.setRoleId(userDTO.getRoleId());
        userRoleDO.setUserId(userDO.getUserId());
        userRoleService.save(userRoleDO);

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/user/get", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取用户信息")
    @Auth
    public BaseResult userGet(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("userId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }

        UserDTO userDto = userService.getUserDto(params);
        userDto.setPassword(null);
        return BaseResult.build(ResultEnum.SUCCESS,userDto);
    }

    @RequestMapping(value = "/user/edit", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("用户编辑")
    @Auth(value = "user:user:edit")
    @Transactional
    public BaseResult userEdit(@RequestBody UserDTO userDTO) {
        //更新用户
        UserDO userDO = userService.get(userDTO.getUserId());
        userDO.setName(userDTO.getName());
        userDO.setEmail(userDTO.getEmail());
        userDO.setMobile(userDTO.getMobile());
        userDO.setDeptId(userDTO.getDeptId());
        userDO.setGmtModified(new Date());
        userService.update(userDO);

        //更新用户和角色的关系
        Map<String,Object> userRoleMap=new HashMap();
        userRoleMap.put("userId",userDTO.getUserId());
        UserRoleDO userRoleDO = userRoleService.getOne(userRoleMap);
        userRoleDO.setRoleId(userDTO.getRoleId());
        userRoleService.update(userRoleDO);
        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/user/remove", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取删除用户")
    @Auth(value = "user:user:remove")
    @Transactional
    public BaseResult userRemove(@RequestBody Map<String, Object> params) {

        if(Objects.isNull(params.get("userId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        //删除用户信息
        Integer userId = Integer.valueOf(params.get("userId") + "");
        userService.remove(userId);

        //删除用户与角色关联信息
        userRoleService.removeByUserId(userId);

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/user/repassword", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据userId重置用户密码")
    @Auth(value = "user:user:repassword")
    public BaseResult repassword(@RequestBody Map<String, Object> params) {

        if(Objects.isNull(params.get("userId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer userId = Integer.valueOf(params.get("userId") + "");
        UserDO userDO = userService.get(userId);
        String reqPassWord = MD5Utils.encrypt(userDO.getUsername(), "123456");
        userDO.setPassword(reqPassWord);
        userDO.setGmtModified(new Date());
        userService.update(userDO);

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/user/upStatus", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据userId禁用和启用用户")
    @Auth(value = "user:user:upStatus")
    @Transactional
    public BaseResult upStatus(@RequestBody Map<String, Object> params) {

        if(Objects.isNull(params.get("userId"))||Objects.isNull(params.get("status"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer userId = Integer.valueOf(params.get("userId") + "");
        Integer status = Integer.valueOf(params.get("status") + "");
        UserDO userDO = userService.get(userId);
        userDO.setStatus(status);
        userDO.setGmtModified(new Date());
        userService.update(userDO);

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/role/list", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("角色列表")
    @Auth(value = "user:role:list")
    public BaseResult roleList(@RequestBody Map<String, Object> params) {
        PageInfo<RoleDO> roleList = roleService.getRoleList(params);
        Map map = new HashMap<>();
        map.put("list", roleList.getList());
        map.put("total", roleList.getTotal());
        return BaseResult.build(ResultEnum.SUCCESS, map);
    }

    @RequestMapping(value = "/role/listAll", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("查询所有角色")
    @Auth
    public BaseResult roleList() {
        List<RoleDO> roleList = roleService.list(null);
        return BaseResult.build(ResultEnum.SUCCESS, roleList);
    }

    @RequestMapping(value = "/role/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("角色添加")
    @Auth(value = "user:role:add")
    @Transactional
    public BaseResult roleAdd(@RequestBody RoleDTO roleDTO) {
        //角色添加
        RoleDO roleDO=new RoleDO();
        roleDO.setRoleName(roleDTO.getRoleName());
        roleDO.setRoleSign(roleDTO.getRoleSign());
        roleDO.setGmtCreate(new Date());
        roleService.save(roleDO);

        //添加角色与资源关联
        for ( Integer menuId:roleDTO.getMenuList()){
            RoleMenuDO roleMenuDO =new RoleMenuDO();
            roleMenuDO.setMenuId(menuId);
            roleMenuDO.setRoleId(roleDO.getRoleId());
            roleMenuService.save(roleMenuDO);
        }

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/role/get", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取角色信息")
    @Auth
    public BaseResult roleGet(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("roleId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        //删除用户信息
        Integer roleId = Integer.valueOf(params.get("roleId") + "");

        RoleDTO roleDTO=new RoleDTO();
        RoleDO roleDO = roleService.get(roleId);
        roleDTO.setRoleId(roleDO.getRoleId());
        roleDTO.setRoleName(roleDO.getRoleName());
        roleDTO.setRoleSign(roleDO.getRoleSign());

        Map menuMap=new HashMap();
        menuMap.put("roleId",roleId);
        List<RoleMenuDO> list = roleMenuService.list(menuMap);
        List<Integer> resources = list.stream()
                .filter(resource -> Objects.nonNull(resource.getMenuId()))
                .map(resource -> resource.getMenuId())
                .collect(Collectors.toList());
        roleDTO.setMenuList(resources);

        return BaseResult.build(ResultEnum.SUCCESS,roleDTO);
    }

    @RequestMapping(value = "/role/edit", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("角色编辑")
    @Auth(value = "user:role:edit")
    @Transactional
    public BaseResult roleEdit(@RequestBody RoleDTO roleDTO) {
        //角色更新
        RoleDO roleDO = roleService.get(roleDTO.getRoleId());
        roleDO.setRoleName(roleDTO.getRoleName());
        roleDO.setRoleSign(roleDTO.getRoleSign());
        roleDO.setGmtModified(new Date());
        roleService.update(roleDO);

        //删除角色与资源关联
        roleMenuService.removeByRoleId(roleDTO.getRoleId());
        //添加角色与资源关联
        for ( Integer menuId:roleDTO.getMenuList()){
            RoleMenuDO roleMenuDO =new RoleMenuDO();
            roleMenuDO.setMenuId(menuId);
            roleMenuDO.setRoleId(roleDO.getRoleId());
            roleMenuService.save(roleMenuDO);
        }

        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/role/remove", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取删除角色")
    @Auth(value = "user:role:remove")
    @Transactional
    public BaseResult roleRemove(@RequestBody Map<String, Object> params) {

        if(Objects.isNull(params.get("roleId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        //删除用户信息
        Integer roleId = Integer.valueOf(params.get("roleId") + "");
        roleService.remove(roleId);

        //删除角色与权限关联信息
        roleMenuService.removeByRoleId(roleId);

        return BaseResult.build(ResultEnum.SUCCESS);
    }


    @RequestMapping(value = "/menu/list", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("菜单列表")
    @Auth(value = "user:menu:list")
    public BaseResult menuList() {
        Map<String, Object> params=new HashMap<>();
        List<MenuDO> list = menuService.list(params);
        return BaseResult.build(ResultEnum.SUCCESS,list);
    }

    @RequestMapping(value = "/menu/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("菜单添加")
    @Auth(value = "user:menu:add")
    public BaseResult menuAdd(@RequestBody MenuDO menuDO) {
        //菜单添加
        menuDO.setGmtCreate(new Date());
        int save = menuService.save(menuDO);
        if (save>0){
            return BaseResult.build(ResultEnum.SUCCESS);
        }
        return BaseResult.build(ResultEnum.FAILURE);
    }

    @RequestMapping(value = "/menu/get", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取菜单")
    @Auth
    public BaseResult menuGet(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("menuId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer menuId = Integer.valueOf(params.get("menuId") + "");
        MenuDO menuDO = menuService.get(menuId);
        return BaseResult.build(ResultEnum.SUCCESS,menuDO);
    }

    @RequestMapping(value = "/menu/edit", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("菜单编辑")
    @Auth(value = "user:menu:edit")
    public BaseResult menuEdit(@RequestBody MenuDO menuDO) {
        //菜单添加
        menuDO.setGmtModified(new Date());
        int update = menuService.update(menuDO);
        if (update>0){
            return BaseResult.build(ResultEnum.SUCCESS);
        }
        return BaseResult.build(ResultEnum.FAILURE);
    }

    @RequestMapping(value = "/menu/remove", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID删除菜单")
    @Auth(value = "user:menu:remove")
    public BaseResult menuRemove(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("menuId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer menuId = Integer.valueOf(params.get("menuId") + "");
        //删除上级，子集也要删除
        menuService.removeLoop(menuId);
        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/menu/tree", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("菜单树形结构")
    @Auth
    public BaseResult menuTree(@RequestBody Map<String, Object> params) {
        Tree<MenuDO> tree = menuService.getTree(params);
        return BaseResult.build(ResultEnum.SUCCESS, tree);
    }

    @RequestMapping(value = "/dept/list", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("部门列表")
    @Auth(value = "user:dept:list")
    public BaseResult deptList() {
        Map<String, Object> params=new HashMap<>();
        List<DeptDO> list = deptService.list(params);
        return BaseResult.build(ResultEnum.SUCCESS,list);
    }

    @RequestMapping(value = "/dept/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("部门添加")
    @Auth(value = "user:dept:add")
    public BaseResult deptAdd(@RequestBody DeptDO deptDO) {
        //菜单添加
        deptDO.setCreateTime(new Date());
        deptDO.setOrderNum(0);
        deptDO.setType(0);
        deptDO.setSign(0);
        int save = deptService.save(deptDO);
        if (save>0){
            return BaseResult.build(ResultEnum.SUCCESS);
        }
        return BaseResult.build(ResultEnum.FAILURE);
    }

    @RequestMapping(value = "/dept/get", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID获取部门")
    @Auth
    public BaseResult deptGet(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("deptId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer deptId = Integer.valueOf(params.get("deptId") + "");
        DeptDO deptDO = deptService.get(deptId);
        return BaseResult.build(ResultEnum.SUCCESS,deptDO);
    }

    @RequestMapping(value = "/dept/edit", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("部门编辑")
    @Auth(value = "user:dept:edit")
    public BaseResult deptEdit(@RequestBody DeptDO deptDO) {
        //菜单添加
        deptDO.setUpdateTime(new Date());
        int update = deptService.update(deptDO);
        if (update>0){
            return BaseResult.build(ResultEnum.SUCCESS);
        }
        return BaseResult.build(ResultEnum.FAILURE);
    }

    @RequestMapping(value = "/dept/remove", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("根据ID删除部门")
    @Auth(value = "user:dept:remove")
    public BaseResult deptRemove(@RequestBody Map<String, Object> params) {
        if(Objects.isNull(params.get("deptId"))){
            return BaseResult.build(ResultEnum.PARAME_ERROR);
        }
        Integer deptId = Integer.valueOf(params.get("deptId") + "");
        //删除上级，子集也要删除
        deptService.removeLoop(deptId);
        return BaseResult.build(ResultEnum.SUCCESS);
    }

    @RequestMapping(value = "/dept/tree", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("所有部门树形结构")
    @Auth
    public BaseResult deptTree() {
        Tree<DeptDO> tree = deptService.getTree();
        return BaseResult.build(ResultEnum.SUCCESS, tree);
    }

    @RequestMapping(value = "/nodeDept/tree", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("节点部门树形结构")
    @Auth
    public BaseResult nodeDeptTree() {
        Tree<DeptDO> tree = deptService.getNodeDeptTree();
        return BaseResult.build(ResultEnum.SUCCESS, tree);
    }

    @RequestMapping(value = "/dept/getDeptList", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ApiOperation("部门列表(可传条件)")
    @Auth
    public BaseResult getDeptList(@RequestBody Map<String, Object> params) {
        List<DeptDO> list = deptService.list(params);
        return BaseResult.build(ResultEnum.SUCCESS,list);
    }

}
